class MockPolling(object):
    def __str__(self):
        return "MockPolling"

class Client(object):
    @staticmethod
    def new():
        return Client()

    def __init__(self):
        self.__polling = None #TODO: use default 
        self.__transport = None # TODO: use default
        self.__running = False


    def polling(self, a_polling):
        if a_polling is not None:
            self.__polling = a_polling
        return self

    def transport(self, a_transport):
        if a_transport is not None:
            self.__transport = a_transport
        return self

    def is_connected(self):
        return self.__transport.is_connected()
    
    def send(self, message):
        return self.__transport.send(message.encode('utf-8'))

    
    def _prepare(self):
        #TODO:
        # 1. polling init
        #TODO: self.__polling.init()
        # 2. protocols init
        self.__transport.connect()
        print("prepare: " + str(self.__transport))

    def _clean(self):
        #TODO:
        # r2. protocols deinit
        self.__transport.disconnect()
        print("_clean: " + str(self.__transport))
        # r1. polling deinit

    def _run(self):
        self.__running = True
        #TODO:

        import time
        while self.__running:
            print("sleep 0.4")
            time.sleep(0.4)

    def run(self):
        try:
            self._prepare()
            self._run()
            self._clean()
        except Exception as e :
            print(e) 
    
    def stop(self):
        if self.__running:
            self.__running = False

    def __str__(self):
        return "transport:[{}],polling:[{}],".format(self.__transport, self.__polling)

    def __del__(self):
        print("client delete")


from mock_transport import MockTransport
import threading
import time
import unittest 

class TestClient(unittest.TestCase):
    def test_main(self):
        client = Client.new() \
            .transport(MockTransport().remote("127.0.0.1", 12345)) \
            .polling(MockPolling())

        print(str(client))

        def run_client(*args):
            if len(args) >= 1:
                client = args[0]
                client.run()
            else:
                print("run client")
        thread = threading.Thread(target=run_client, args=(client,))
        thread.start()

        while not client.is_connected():
            time.sleep(0.1)

        client.send("hello world")
        client.stop()

        thread.join()

if __name__ == "__main__":
    unittest.main(verbosity=2)
